package com.mall.b2c.hessian.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;





import com.mall.b2c.enums.OrderStatus;
import com.mall.b2c.service.OrderLogService;
import com.mall.b2c.util.SerialNumberUtil;

import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.mall.b2c.bean.OrderBean;
import com.mall.b2c.bean.PayInfo;
import com.mall.b2c.domain.member.MemberDomain;
import com.mall.b2c.domain.order.CartDomain;
import com.mall.b2c.domain.order.OrderDomain;
import com.mall.b2c.hessian.TradeHessian;
import com.mall.b2c.plugin.payment.IPaymentEvent;
import com.mall.b2c.plugin.payment.PaymentPluginBundle;
import com.mall.b2c.service.CartService;
import com.mall.b2c.service.DeliveryMethodService;
import com.mall.b2c.service.OrderService;
import com.mall.b2c.service.PaymentDetailService;
import com.mall.b2c.util.SettingUtils;
import com.mall.common.enums.PayType;
import com.mall.common.exception.NoticeException;
import com.mall.common.hessian.impl.BaseHessianImpl;
import com.mall.common.hibernate.Finder;
import com.mall.common.plugin.IPlugin;

@Service("b2cTradeHessian")
public class TradeHessianImpl extends BaseHessianImpl implements TradeHessian {
	@Resource private PaymentDetailService paymentDetailService;
	@Resource private OrderService orderService;
	@Resource private CartService cartService;
	@Resource private PaymentPluginBundle paymentPluginBundle;
	@Resource private OrderLogService orderLogService;
	@Resource private DeliveryMethodService deliveryMethodService;

	@Override
	public String getPaymentDetailPager(Long memberId, Date startDate, Date endDate, 
			Integer detailType, Integer pagerNumber) {
		return objToJson(paymentDetailService.getPaymentDetailPager(memberId, startDate, endDate, detailType, pagerNumber));
	}

	@Override
	public BigDecimal getPaymentSummarize(Long memberId, Boolean isIncome,
			Date startDate, Date endDate) {
		Finder finder = Finder.create("select sum(bean.amount) from PaymentDetailDomain bean where bean.member.id = :memberId");
		if(isIncome != null){
			finder.append(" and bean.amount").append(isIncome?">0":"<0");
		}
		if(startDate != null){
			finder.append(" and bean.createDate >= :startDate");
			finder.setParam("startDate", startDate);
		}
		if(endDate != null){
			finder.append(" and bean.createDate <= :endDate");
			finder.setParam("endDate", endDate);
		}
		finder.setParam("memberId", memberId);
		Object obj = finder.findUniqueByHQL();
		if(obj == null){
			return BigDecimal.ZERO;
		}
		BigDecimal total = new BigDecimal(obj.toString());
		return total.signum() < 0?total.negate():total;
	}

	@Override
	public String getOrderPager(String keyword, Long memberId, Date startDate, Date endDate, Integer orderStatus, Integer pagerNumber) {
		return objToJson(orderService.getOrderPager(keyword, memberId, startDate, endDate, orderStatus, pagerNumber));
	}

	@Override
	public String getDeliveryMethods(Long receiverId, Long memberId, BigDecimal weight) {
		return listToJson(deliveryMethodService.getAvaliableDeliveries(receiverId, memberId, weight));
	}

	@Override
	public String checkCartItems(Long memberId, Long[] cartItems) {
		return cartService.checkItems(memberId, cartItems).toString();
	}

	@Override
	public String checkCartItems2(Long memberId, Long[] cartItems) {
		return cartService.checkItems2(memberId, cartItems).toString();
	}

	@Override
	public String createOrder(Long storeId, Long memberId, Long[] cartItemIds,
			Integer payType, Long receiverId, Long deliveryMethodId,
			String postscript, Boolean isInvoice, Integer invoiceType,
			String invoiceTitle) {
		return orderService.createOrder(storeId, memberId, cartItemIds, payType, receiverId, deliveryMethodId, postscript, isInvoice, invoiceType, invoiceTitle);
	}

	@Override
	public String checkGoods(Long memberId, Long goodsId, Integer num) {
		return orderService.checkGoods(memberId, goodsId, num).toString();
	}

	@Override
	public String buyNow(Long storeId, Long memberId, Long goodsId, Integer num,
			Integer payType, Long receiverId, Long deliveryMethodId,
			String postscript, Boolean isInvoice, Integer invoiceType,
			String invoiceTitle) {
		return orderService.buyNow(storeId, memberId, goodsId, num, payType, receiverId, deliveryMethodId, postscript, isInvoice, invoiceType, invoiceTitle);
	}

	@Override
	public String getOrderInfo(Long memberId, String orderNo) {
		OrderDomain order;
		if(orderNo.startsWith(SerialNumberUtil.TRADE_SN_PREFIX)){
			order = orderService.getOrderByTradeNo(orderNo, memberId);
		}else{
			order = orderService.getOrderByMemberId(memberId, orderNo);
		}
		return objToJson(new OrderBean(order));
	}

	@Override
	public String getPayInfo(Long memberId, String orderNo) {
		OrderDomain order = orderService.getOrderByMemberId(memberId, orderNo);
		if(order == null){
			throw new NoticeException("订单不存在");
		}
		JSONObject jObj = new JSONObject();
		if(order.getPayType() == PayType.cashOnDelivery){
			orderService.payCash(memberId, orderNo);
			jObj.put("isFinish", true);
		} else if (order.getPayType() == PayType.wftalipaysm
				|| order.getPayType() == PayType.wftweixinsm) {
			if(order.getIsExpired()){
				throw new NoticeException("订单已失效");
			}
			MemberDomain member = order.getMember();
			BigDecimal deposit = member.getDeposit();
			BigDecimal totalAmount = order.getTotalAmount();
			if(totalAmount.compareTo(deposit) > 0){
				jObj.put("deposit", deposit);
			}else{
				jObj.put("deposit", totalAmount);
			}
			jObj.put("total", totalAmount);
			jObj.put("shipFee", order.getShipFee());
			jObj.put("orderNo", order.getOrderNo());

			jObj.put("isFinish", false);
			if(order.getOrderStatus() != OrderStatus.waitBuyerPay){
				jObj.put("isFinish", true);
			}else{
				PayInfo info = new PayInfo();
				String BankInfo = "";
				switch (order.getPayType()) {
					case wftalipaysm:
						BankInfo = "108001";
						break;
					case wftweixinsm:
						BankInfo = "108002";
						break;
				}
				info.setBankInfo(BankInfo);
				info.setMemberId(memberId);
				info.setOrderNo(orderNo);
				info.setUseDeposit(true);
				jObj.putAll(orderService.checkWftPayInfo(info));
			}
		}else {
			if(order.getIsExpired()){
				throw new NoticeException("订单已失效");
			}
			jObj.put("isFinish", false);
			if(order.getOrderStatus() != OrderStatus.waitBuyerPay){
				jObj.put("isFinish", true);
			}
			MemberDomain member = order.getMember();
			BigDecimal deposit = member.getDeposit();
			BigDecimal totalAmount = order.getTotalAmount();
			if(totalAmount.compareTo(deposit) > 0){
				jObj.put("deposit", deposit);
			}else{
				jObj.put("deposit", totalAmount);
			}
			jObj.put("payTypes", SettingUtils.getDictionaryDataListForJSON("106"));
			jObj.put("total", totalAmount);
			jObj.put("shipFee", order.getShipFee());
			jObj.put("orderNo", order.getOrderNo());
		}
		jObj.put("address", order.getAreaName()+order.getAddress());
		jObj.put("contact", order.getContact());
		jObj.put("payType", order.getPayType());
		return jObj.toString();
	}

	@Override
	public String checkPayInfo(PayInfo payInfo){
		if(payInfo == null){
			throw new NoticeException("付款信息不正确");
		}
		return orderService.checkPayInfo(payInfo).toString();
	}

	@Override
	public String pay(Long memberId, Map<String, String> params) throws Exception {
		if(memberId == null){
			throw new NoticeException("会员不存在");
		}
		List<IPlugin> plugins = paymentPluginBundle.getPluginList();
		for (IPlugin plugin : plugins) {
			IPaymentEvent pay = (IPaymentEvent) plugin;
			String tradeNo = pay.getTradeNo(params);
			if(!StringUtils.isEmpty(tradeNo)){
				return pay.onReturn(memberId, params);
			}
		}
		throw new NoticeException("无法找到支付接口，请联系客服!");
	}

	@Override
	public String getCartItemInfo(Long memberId, String key, boolean withItem) {
		CartDomain cart = cartService.getCurrent(memberId, key);
		return objToJson(cart.getCartInfo(withItem));
	}

	@Override
	public String getCartItemList(Long memberId, Long[] itemIds) {
		Finder finder = Finder.create("select new com.mall.b2c.bean.CartItemBean(bean) from CartItemDomain bean where bean.cart.member.id=:memberId and bean.id in (:itemIds)");
		finder.setParam("memberId", memberId);
		finder.setParamList("itemIds", itemIds);
		return listToJson(finder.findHQLList());
	}

	@Override
	public String getShopCartItemList(Long memberId, Long[] itemIds) {
		Finder finder = Finder.create("select new com.mall.b2c.bean.ShopCartItemBean(bean) from ShopCartItemDomain bean where bean.cart.member.id=:memberId and bean.id in (:itemIds)");
		finder.setParam("memberId", memberId);
		finder.setParamList("itemIds", itemIds);
		return listToJson(finder.findHQLList());
	}

	@Override
	public String addCartItem(Long memberId, String key, Long goodsId, Integer quantity) {
		return cartService.addCart(memberId, key, goodsId, quantity).toString();
	}

	@Override
	public String addCartItem2(Long memberId, String key, Long id, Integer quantity) {
		return cartService.addCart2(memberId, key, id, quantity).toString();
	}

	@Override
	public String batchAddCartItem(Long memberId, Long[] goodsIds) {
		return cartService.batchAddCartItem(memberId, goodsIds).toString();
	}

	@Override
	public void modifyCartItem(Long memberId, Long cartItemId, Integer quantity) {
		cartService.modifyCartItem(memberId, cartItemId, quantity);
	}

	@Override
	public void modifyCartItem2(Long memberId, Long cartItemId, Integer quantity) {
		cartService.modifyCartItem2(memberId, cartItemId, quantity);
	}

	@Override
	public String deleteCartItems(Long memberId, Long[] cartItemIds) {
		return cartService.deletecartItem(memberId, cartItemIds).toString();
	}

	@Override
	public String deleteCartItems2(Long memberId, Long[] cartItemIds) {
		return cartService.deletecartItem2(memberId, cartItemIds).toString();
	}

	@Override
	public void cancelOrder(Long memberId, String orderNo) {
		orderService.cancelOrder(orderNo, memberId);
	}

	@Override
	public void deleteOrder(Long memberId, String orderNo) {
		orderService.deleteOrder(orderNo, memberId);
	}

	@Override
	public void confirmReceive(Long memberId, String orderNo) {
		orderService.confirmReceive(orderNo, memberId);
	}

	@Override
	public String findOrderList(Long memberId, Integer count) {
		String hql = "select new com.mall.b2c.bean.OrderBean(bean) from OrderDomain bean where bean.member.id = :memberId and bean.isDelete = false order by bean.createDate desc";
		Finder finder = Finder.create(hql);
		finder.setParam("memberId", memberId);
		if(count == null){
			count = 10;
		}
		finder.setMaxResults(count);
		return listToJson(finder.findHQLList());
	}

	@Override
	public Long orderCount(Long memberId, String orderStatus) {
		String hql = "select count(bean) from OrderDomain bean where bean.member.id = :memberId and bean.orderStatus = :orderStatus and bean.isDelete = false";
		Finder finder = Finder.create(hql);
		finder.setParam("memberId", memberId);
		finder.setParam("orderStatus", OrderStatus.valueOf(orderStatus));
		return (Long) finder.findUniqueByHQL();
	}

	@Override
	public String findOrderLogs(Long memberId, String orderNo) {
		return listToJson(orderLogService.findLogsByMemberId(orderNo, memberId));
	}
}
